package com.hsy.managemoney.modules.web;

import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Bitmap;
import android.net.Uri;
import android.net.http.SslError;
import android.os.Build;
import android.os.Message;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.view.InputEvent;
import android.view.KeyEvent;
import android.view.View;
import android.webkit.ClientCertRequest;
import android.webkit.ConsoleMessage;
import android.webkit.GeolocationPermissions;
import android.webkit.HttpAuthHandler;
import android.webkit.JsPromptResult;
import android.webkit.JsResult;
import android.webkit.PermissionRequest;
import android.webkit.SslErrorHandler;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceError;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import android.webkit.WebStorage;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import java.lang.reflect.Field;

/**
 * Created by MartinKent on 2016/8/16.
 */
public class DPWebView extends WebView {
    private Client mClient = new Client();

    public DPWebView(Context context) {
        super(context);
        init(context);
    }

    public DPWebView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public DPWebView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    private void init(Context context) {
        final WebSettings settings = getSettings();
        settings.setJavaScriptEnabled(true);
        settings.setJavaScriptCanOpenWindowsAutomatically(true);
        settings.setCacheMode(WebSettings.LOAD_NO_CACHE);
        settings.setSupportZoom(true);
        settings.setBuiltInZoomControls(true);
        settings.setUseWideViewPort(true);

        super.setWebChromeClient(new MyWebChromeClient());
        super.setWebViewClient(new MyWebViewClient());

        setClient(new Client());
    }

    public void setClient(@NonNull Client mClient) {
        this.mClient = mClient;
        try {
            Field cls = Client.class.getDeclaredField("webView");
            cls.setAccessible(true);
            cls.set(this.mClient, this);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
            throw new RuntimeException("Webview set failed.");
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            throw new RuntimeException("Webview set failed.");
        }
    }

    @Deprecated
    @Override
    public void setWebChromeClient(WebChromeClient client) {

    }

    @Deprecated
    @Override
    public void setWebViewClient(WebViewClient client) {

    }

    private class MyWebChromeClient extends WebChromeClient {
        @Override
        public void onProgressChanged(WebView view, int newProgress) {
            mClient.onProgressChanged(this, view, newProgress);
        }

        @Override
        public void onReceivedTitle(WebView view, String title) {
            mClient.onReceivedTitle(this, view, title);
        }

        @Override
        public void onReceivedIcon(WebView view, Bitmap icon) {
            mClient.onReceivedIcon(this, view, icon);
        }

        @Override
        public void onReceivedTouchIconUrl(WebView view, String url, boolean precomposed) {
            mClient.onReceivedTouchIconUrl(this, view, url, precomposed);
        }

        @Override
        public void onShowCustomView(View view, CustomViewCallback callback) {
            mClient.onShowCustomView(this, view, callback);
        }

        @Override
        public void onShowCustomView(View view, int requestedOrientation, CustomViewCallback callback) {
            mClient.onShowCustomView(this, view, requestedOrientation, callback);
        }

        @Override
        public void onHideCustomView() {
            mClient.onHideCustomView(this);
        }

        @Override
        public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) {
            return mClient.onCreateWindow(this, view, isDialog, isUserGesture, resultMsg);
        }

        @Override
        public void onRequestFocus(WebView view) {
            mClient.onRequestFocus(this, view);
        }

        @Override
        public void onCloseWindow(WebView window) {
            mClient.onCloseWindow(this, window);
        }

        @Override
        public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
            return mClient.onJsAlert(this, view, url, message, result);
        }

        @Override
        public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
            return mClient.onJsConfirm(this, view, url, message, result);
        }

        @Override
        public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
            return mClient.onJsPrompt(this, view, url, message, defaultValue, result);
        }

        @Override
        public boolean onJsBeforeUnload(WebView view, String url, String message, JsResult result) {
            return mClient.onJsBeforeUnload(this, view, url, message, result);
        }

        @Override
        public void onExceededDatabaseQuota(String url, String databaseIdentifier, long quota, long estimatedDatabaseSize, long totalQuota, WebStorage.QuotaUpdater quotaUpdater) {
            mClient.onExceededDatabaseQuota(this, url, databaseIdentifier, quota, estimatedDatabaseSize, totalQuota, quotaUpdater);
        }

        @Override
        public void onReachedMaxAppCacheSize(long requiredStorage, long quota, WebStorage.QuotaUpdater quotaUpdater) {
            mClient.onReachedMaxAppCacheSize(this, requiredStorage, quota, quotaUpdater);
        }

        @Override
        public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
            mClient.onGeolocationPermissionsShowPrompt(this, origin, callback);
        }

        @Override
        public void onGeolocationPermissionsHidePrompt() {
            mClient.onGeolocationPermissionsHidePrompt(this);
        }

        @Override
        public void onPermissionRequest(PermissionRequest request) {
            mClient.onPermissionRequest(this, request);
        }

        @Override
        public void onPermissionRequestCanceled(PermissionRequest request) {
            mClient.onPermissionRequestCanceled(this, request);
        }

        @Override
        public boolean onJsTimeout() {
            return mClient.onJsTimeout(this);
        }

        @Override
        public void onConsoleMessage(String message, int lineNumber, String sourceID) {
            mClient.onConsoleMessage(this, message, lineNumber, sourceID);
        }

        @Override
        public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
            return mClient.onConsoleMessage(this, consoleMessage);
        }

        @Override
        public Bitmap getDefaultVideoPoster() {
            Bitmap b = mClient.getDefaultVideoPoster(this);
            return null == b ? super.getDefaultVideoPoster() : b;
        }

        @Override
        public View getVideoLoadingProgressView() {
            return mClient.getVideoLoadingProgressView(this);
        }

        @Override
        public void getVisitedHistory(ValueCallback<String[]> callback) {
            mClient.getVisitedHistory(this, callback);
        }

        @Override
        public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
            return mClient.onShowFileChooser(this, webView, filePathCallback, fileChooserParams);
        }
    }

    private class MyWebViewClient extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            return mClient.shouldOverrideUrlLoading(this, view, url);
        }

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            mClient.onPageStarted(this, view, url, favicon);
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            mClient.onPageFinished(this, view, url);
        }

        @Override
        public void onLoadResource(WebView view, String url) {
            mClient.onLoadResource(this, view, url);
        }

        @Override
        public void onPageCommitVisible(WebView view, String url) {
            mClient.onPageCommitVisible(this, view, url);
        }

        @Override
        public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
            WebResourceResponse res = mClient.shouldInterceptRequest(this, view, url);
            return null == res ? super.shouldInterceptRequest(view, url) : res;
        }

        @Override
        public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
            WebResourceResponse res = mClient.shouldInterceptRequest(this, view, request);
            return null == res ? super.shouldInterceptRequest(view, request) : res;
        }

        @Override
        public void onTooManyRedirects(WebView view, Message cancelMsg, Message continueMsg) {
            mClient.onTooManyRedirects(this, view, cancelMsg, continueMsg);
        }

        @Override
        public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
            mClient.onReceivedError(this, view, errorCode, description, failingUrl);
        }

        @Override
        public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
            mClient.onReceivedError(this, view, request, error);
        }

        @Override
        public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
            mClient.onReceivedHttpError(this, view, request, errorResponse);
        }

        @Override
        public void onFormResubmission(WebView view, Message dontResend, Message resend) {
            mClient.onFormResubmission(this, view, dontResend, resend);
        }

        @Override
        public void doUpdateVisitedHistory(WebView view, String url, boolean isReload) {
            mClient.doUpdateVisitedHistory(this, view, url, isReload);
        }

        @Override
        public void onReceivedSslError(WebView view, SslErrorHandler shandler, SslError error) {
            mClient.onReceivedSslError(this, view, shandler, error);
        }

        @Override
        public void onReceivedClientCertRequest(WebView view, ClientCertRequest request) {
            mClient.onReceivedClientCertRequest(this, view, request);
        }

        @Override
        public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler shandler, String host, String realm) {
            mClient.onReceivedHttpAuthRequest(this, view, shandler, host, realm);
        }

        @Override
        public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event) {
            return mClient.shouldOverrideKeyEvent(this, view, event);
        }

        @Override
        public void onUnhandledKeyEvent(WebView view, KeyEvent event) {
            mClient.onUnhandledKeyEvent(this, view, event);
        }

        @Override
        public void onUnhandledInputEvent(WebView view, InputEvent event) {
            mClient.onUnhandledInputEvent(this, view, event);
        }

        @Override
        public void onScaleChanged(WebView view, float oldScale, float newScale) {
            mClient.onScaleChanged(this, view, oldScale, newScale);
        }

        @Override
        public void onReceivedLoginRequest(WebView view, String realm, String account, String args) {
            mClient.onReceivedLoginRequest(this, view, realm, account, args);
        }
    }

    public static class Client {
        private DPWebView webView;

        public boolean dispatchKeyEvent(KeyEvent event) {
            return false;
        }

        public DPWebView getWebView() {
            return webView;
        }

        public void onProgressChanged(WebChromeClient client, WebView view, int newProgress) {

        }

        public void onReceivedTitle(WebChromeClient client, WebView view, String title) {

        }

        public void onReceivedIcon(WebChromeClient client, WebView view, Bitmap icon) {

        }

        public void onReceivedTouchIconUrl(WebChromeClient client, WebView view, String url, boolean precomposed) {

        }

        public void onShowCustomView(WebChromeClient client, View view, WebChromeClient.CustomViewCallback callback) {

        }

        public void onShowCustomView(WebChromeClient client, View view, int requestedOrientation, WebChromeClient.CustomViewCallback callback) {

        }

        public void onHideCustomView(WebChromeClient client) {

        }

        public boolean onCreateWindow(WebChromeClient client, WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) {
            return false;
        }

        public void onRequestFocus(WebChromeClient client, WebView view) {
            client.onRequestFocus(view);
        }

        public void onCloseWindow(WebChromeClient client, WebView window) {

        }

        public boolean onJsAlert(WebChromeClient client, WebView view, String url, String message, JsResult result) {
            return false;
        }

        public boolean onJsConfirm(WebChromeClient client, WebView view, String url, String message, JsResult result) {
            return false;
        }

        public boolean onJsPrompt(WebChromeClient client, WebView view, String url, String message, String defaultValue, JsPromptResult result) {
            return false;
        }

        public boolean onJsBeforeUnload(WebChromeClient client, WebView view, String url, String message, JsResult result) {
            return false;
        }

        public void onExceededDatabaseQuota(WebChromeClient client, String url, String databaseIdentifier, long quota, long estimatedDatabaseSize, long totalQuota, WebStorage.QuotaUpdater quotaUpdater) {

        }

        public void onReachedMaxAppCacheSize(WebChromeClient client, long requiredStorage, long quota, WebStorage.QuotaUpdater quotaUpdater) {

        }

        public void onGeolocationPermissionsShowPrompt(WebChromeClient client, String origin, GeolocationPermissions.Callback callback) {

        }

        public void onGeolocationPermissionsHidePrompt(WebChromeClient client) {

        }

        @TargetApi(Build.VERSION_CODES.LOLLIPOP)
        public void onPermissionRequest(WebChromeClient client, PermissionRequest request) {

        }

        @TargetApi(Build.VERSION_CODES.LOLLIPOP)
        public void onPermissionRequestCanceled(WebChromeClient client, PermissionRequest request) {

        }

        public boolean onJsTimeout(WebChromeClient client) {
            return client.onJsTimeout();
        }

        public void onConsoleMessage(WebChromeClient client, String message, int lineNumber, String sourceID) {

        }

        public boolean onConsoleMessage(WebChromeClient client, ConsoleMessage consoleMessage) {
            return false;
        }

        public Bitmap getDefaultVideoPoster(WebChromeClient client) {
            return null;
        }

        public View getVideoLoadingProgressView(WebChromeClient client) {
            return null;
        }

        public void getVisitedHistory(WebChromeClient client, ValueCallback<String[]> callback) {

        }

        @TargetApi(Build.VERSION_CODES.LOLLIPOP)
        public boolean onShowFileChooser(WebChromeClient client, WebView webView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) {
            return false;
        }

        public boolean shouldOverrideUrlLoading(WebViewClient client, WebView view, String url) {
            return false;
        }

        public void onPageStarted(WebViewClient client, WebView view, String url, Bitmap favicon) {

        }

        public void onPageFinished(WebViewClient client, WebView view, String url) {

        }

        public void onLoadResource(WebViewClient client, WebView view, String url) {

        }

        @TargetApi(Build.VERSION_CODES.M)
        public void onPageCommitVisible(WebViewClient client, WebView view, String url) {

        }

        public WebResourceResponse shouldInterceptRequest(WebViewClient client, WebView view, String url) {
            return null;
        }

        @TargetApi(Build.VERSION_CODES.LOLLIPOP)
        public WebResourceResponse shouldInterceptRequest(WebViewClient client, WebView view, WebResourceRequest request) {
            return null;
        }

        public void onTooManyRedirects(WebViewClient client, WebView view, Message cancelMsg, Message continueMsg) {

        }

        public void onReceivedError(WebViewClient client, WebView view, int errorCode, String description, String failingUrl) {

        }

        @TargetApi(Build.VERSION_CODES.M)
        public void onReceivedError(WebViewClient client, WebView view, WebResourceRequest request, WebResourceError error) {

        }

        @TargetApi(Build.VERSION_CODES.M)
        public void onReceivedHttpError(WebViewClient client, WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {

        }

        public void onFormResubmission(WebViewClient client, WebView view, Message dontResend, Message resend) {

        }

        public void doUpdateVisitedHistory(WebViewClient client, WebView view, String url, boolean isReload) {

        }

        public void onReceivedSslError(WebViewClient client, WebView view, SslErrorHandler handler, SslError error) {

        }

        @TargetApi(Build.VERSION_CODES.LOLLIPOP)
        public void onReceivedClientCertRequest(WebViewClient client, WebView view, ClientCertRequest request) {

        }

        public void onReceivedHttpAuthRequest(WebViewClient client, WebView view, HttpAuthHandler handler, String host, String realm) {

        }

        public boolean shouldOverrideKeyEvent(WebViewClient client, WebView view, KeyEvent event) {
            return false;
        }

        public void onUnhandledKeyEvent(WebViewClient client, WebView view, KeyEvent event) {

        }

        @TargetApi(Build.VERSION_CODES.LOLLIPOP)
        public void onUnhandledInputEvent(WebViewClient client, WebView view, InputEvent event) {

        }

        public void onScaleChanged(WebViewClient client, WebView view, float oldScale, float newScale) {

        }

        public void onReceivedLoginRequest(WebViewClient client, WebView view, String realm, String account, String args) {

        }
    }
}
